<!DOCTYPE html>
<html>
<head>
<title>Charged Sphere with Cavity</title>
</head>
<body>
<canvas id="canvas" width="500" height="420" style="background-color: white;"></canvas>
<script>
    const canvas = document.getElementById('canvas');
    const ctx = canvas.getContext('2d');

    // Parameters based on the image proportions
    const centerX = 250;
    const centerY = 200;
    const R = 120;
    const O_prime_dist = 50; // distance OO'
    const r = 60;
    
    const centerO = { x: centerX, y: centerY };
    const centerO_prime = { x: centerX + O_prime_dist, y: centerY };
    const pointP = { x: centerX - 70, y: centerY };
    const pointP_prime = { x: centerX - 150, y: centerY };

    // Clear canvas
    ctx.fillStyle = 'white';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 1. Draw the shaded sphere
    ctx.beginPath();
    ctx.arc(centerO.x, centerO.y, R, 0, 2 * Math.PI);
    ctx.fillStyle = '#E8E8E8'; // Light gray
    ctx.fill();

    // 2. "Dig out" the small sphere (cavity) by drawing a white circle on top
    ctx.beginPath();
    ctx.arc(centerO_prime.x, centerO_prime.y, r, 0, 2 * Math.PI);
    ctx.fillStyle = 'white';
    ctx.fill();

    // 3. Draw the outlines
    ctx.lineWidth = 2;
    ctx.strokeStyle = 'black';
    ctx.beginPath();
    ctx.arc(centerO.x, centerO.y, R, 0, 2 * Math.PI);
    ctx.stroke();
    
    ctx.beginPath();
    ctx.arc(centerO_prime.x, centerO_prime.y, r, 0, 2 * Math.PI);
    ctx.stroke();

    // 4. Draw the horizontal line
    ctx.beginPath();
    ctx.lineWidth = 1;
    ctx.strokeStyle = 'black';
    ctx.moveTo(pointP_prime.x - 30, centerY);
    ctx.lineTo(centerO_prime.x + r + 30, centerY);
    ctx.stroke();

    // 5. Draw the points
    function drawPoint(x, y) {
        ctx.beginPath();
        ctx.arc(x, y, 3.5, 0, 2 * Math.PI);
        ctx.fillStyle = '#333333';
        ctx.fill();
    }
    drawPoint(pointP_prime.x, pointP_prime.y);
    drawPoint(pointP.x, pointP.y);
    drawPoint(centerO.x, centerO.y);
    drawPoint(centerO_prime.x, centerO_prime.y);

    // 6. Draw the labels for points
    ctx.fillStyle = 'black';
    ctx.font = "italic 20px 'Times New Roman'";
    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';
    ctx.fillText("P'", pointP_prime.x, pointP_prime.y - 5);
    ctx.fillText("P", pointP.x, pointP.y - 5);
    ctx.fillText("O", centerO.x, centerO.y - 5);
    ctx.fillText("O'", centerO_prime.x, centerO_prime.y - 5);

    // 7. Draw radius R with arrow
    function drawArrow(ctx, fromx, fromy, tox, toy) {
        const headlen = 10;
        const dx = tox - fromx;
        const dy = toy - fromy;
        const angle = Math.atan2(dy, dx);
        ctx.moveTo(fromx, fromy);
        ctx.lineTo(tox, toy);
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6));
        ctx.moveTo(tox, toy);
        ctx.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6));
    }
    
    ctx.beginPath();
    ctx.lineWidth = 1.5;
    const angleR = (235 * Math.PI) / 180; // Angle for R vector, adjusted to match image
    const endRx = centerO.x + R * Math.cos(angleR);
    const endRy = centerO.y + R * Math.sin(angleR);
    drawArrow(ctx, centerO.x, centerO.y, endRx, endRy);
    ctx.stroke();
    // Label for R
    ctx.font = "italic 22px 'Times New Roman'";
    ctx.fillText("R", centerO.x - 45, centerO.y + 60);

    // 8. Draw radius r with arrow
    ctx.beginPath();
    ctx.lineWidth = 1.5;
    const angle_r = (-45 * Math.PI) / 180; // Angle for r vector
    const end_r_x = centerO_prime.x + r * Math.cos(angle_r);
    const end_r_y = centerO_prime.y + r * Math.sin(angle_r);
    drawArrow(ctx, centerO_prime.x, centerO_prime.y, end_r_x, end_r_y);
    ctx.stroke();
    // Label for r
    ctx.fillText("r", centerO_prime.x + 30, centerO_prime.y + 30);

    // 9. Draw the bottom text label
    ctx.font = '20px "SimSun", "Songti SC"';
    ctx.fillStyle = 'black';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';
    ctx.fillText("习题 7-22 图", canvas.width / 2, canvas.height - 10);

</script>
</body>
</html>